# @Time : 2024-10-25 17:25
# @Author : Fioman 
# @Phone : 13149920693
"""
为什么说只要实现了__get__  __set__ __delete__ 方法中任何一个方法,都可以被当成数属性描述符类呢
非数据描述符: 只实现了 __get__,只能获取属性的值,如果赋值,属性描述符会被覆盖掉
数据描述符: 实现了__get__ __set__ __delete__
"""

# region 1. 非数据描述符  只实现 __get__ 方法
"""
没有控制对属性赋值的能力,如果对属性赋值,实例的__dict__会覆盖掉描述符的效果.
当一个属性是非数据描述符的时候:
1) 第一次访问, 调用__get__方法,可能会进行一些计算或者操作.
2) 如果对该属性赋值,属性将直接存储在实例的__dict__中,并且后续的访问不再调用描述符的__get__方法, 
     而是直接范湖实例中的值.
"""


# 一个简单的非数据描述符
class NonDataDescriptor:
    def __init__(self, value):
        self.value = value

    def __get__(self, instance, owner):
        print(f"Getting Value: {self.value}")
        return self.value


class MyClass:
    nonDataAttr = NonDataDescriptor(42)


obj = MyClass()
print(obj.nonDataAttr)
print(obj.__dict__)  # 这个时候__dict__为空
# 对属性进行赋值的时候,直接会赋值到__dict__中获取值
obj.nonDataAttr = 100  # 因为没有__set__方法,所以会直接在__dict__中添加属性
print(obj.__dict__)


# 所以 __set__的优先级是高于在__dict__中赋值的,但是访问的时候__dict__又是高度__get__方法的
# 所以只要实现了__set__就不会在__dict__中保存属性了,后续可以验证一下

class DataDescriptor:
    def __init__(self, value):
        self.value = value

    def __get__(self, instance, owner):
        print(f"Getting Value: {self.value}")
        return self.value

    def __set__(self, instance, value):
        self.value = value
        print(f"Setting Value: {self.value}")


class Simple:
    dataAttr = DataDescriptor(42)


print("simple info show --------------")
simple = Simple()
print(simple.dataAttr)
print(simple.__dict__)
simple.dataAttr = 100
print(simple.__dict__)  # 字典还是空,所以如果实现了__set__方法,然后就不会保存到__dict__字典中了

# endregion
